﻿using ACS.SPiiPlusNET;
using System.Windows;
using Company.Hardware.Acs;
using Company.Axis;
using Company.Config;
using Company.UI.Views;
using Company.Share.Events;
using System.Windows.Threading;

namespace Company.Main.ViewModels
{
    public class MotionViewModel : BindableBase
    {
        private List<AxisConfig> _Axes;

        public List<AxisConfig> Axes
        {
            get { return _Axes; }
            set { _Axes = value; }
        }
        private AxisProvider _AxisProvider;

        public AxisProvider AxisProvider
        {
            get { return _AxisProvider; }
            set { _AxisProvider = value; }
        }
        private bool IsRunningUpData;
        // 定时器（用于更新轴相关数据）
        private DispatcherTimer UpdataAxesTimer = new DispatcherTimer();
        public AcsControllerProvider AcsControllerProvider { get; private set; }
        public List<PositioningAxisControlView> PositioningAxisControlViews { get; private set; }
        public MotionViewModel(ConfigProvider configProvider,
            AxisProvider axisProvider,
            AcsControllerProvider acsControllerProvider,
            IEventAggregator eventAggregator)
        {
            Axes = configProvider.AxesConfig.AxisConfigs;
            AxisProvider = axisProvider;
            AcsControllerProvider = acsControllerProvider;

            PositioningAxisControlViews = new List<PositioningAxisControlView>();
            foreach (var item in Axes)
            {
                var axisParameter = new AxisMotionParameter()
                {
                    CurrentAxisId = item.AxisId,
                    NameOfAxis = item.NameOfAxis,
                };
                var axisState = new PositioningAxisState();
                AxisProvider.AcsMotionAxes.Add(new AcsMotionAxis() { AxisParameter = axisParameter, AxisState = axisState });
            }
            foreach (var item in AxisProvider.AcsMotionAxes)
            {
                PositioningAxisControlViews.Add(new PositioningAxisControlView()
                {
                    Axis = item
                });
            }
            // 事件注册
            AcsControllerProvider.AcsController.AcsDisconnecting += () =>
            {
                // 停止线程刷新数据
                UpdataAxesTimer.Stop();
                IsRunningUpData = false;
            };
            UpdataAxesTimer.Interval = TimeSpan.FromMilliseconds(300);
            UpdataAxesTimer.Tick += (s, e) => GetDataFromController();
            // 使用事件聚合器订阅
            eventAggregator.GetEvent<AcsControllerConnectedEvent>().Subscribe((obj) =>
            {
                if (obj)
                {
                    //开始线程刷新数据
                    if (!IsRunningUpData)
                    {
                        UpdataAxesTimer.Start();
                        IsRunningUpData = true;
                    }
                    // 连接后更新数据
                    Initialize();
                }
            });
        }
        /// <summary>
        /// 控件初始化
        /// </summary>
        private void Initialize()
        {
            foreach (var item in AxisProvider.AcsMotionAxes)
            {
                // 更新数据
                item.AxisParameter.TargetSoftLeftLimit = (double)AcsControllerProvider.AcsController.ReadVariable("SLLIMIT", ProgramBuffer.ACSC_NONE, item.AxisParameter.CurrentAxisId, item.AxisParameter.CurrentAxisId);
                item.AxisParameter.TargetSoftRightLimit = (double)AcsControllerProvider.AcsController.ReadVariable("SRLIMIT", ProgramBuffer.ACSC_NONE, item.AxisParameter.CurrentAxisId, item.AxisParameter.CurrentAxisId);
                // 获取当前加速度
                item.AxisParameter.TargetAcceleration = (double)AcsControllerProvider.AcsController.AcsInstance.GetAcceleration((ACS.SPiiPlusNET.Axis)item.AxisParameter.CurrentAxisId);
                // 获取当前减速度
                item.AxisParameter.TargetDeceleration = (double)AcsControllerProvider.AcsController.AcsInstance.GetDeceleration((ACS.SPiiPlusNET.Axis)item.AxisParameter.CurrentAxisId);
                // 获取加加速
                item.AxisParameter.TargetJerk = (double)AcsControllerProvider.AcsController.AcsInstance.GetJerk((ACS.SPiiPlusNET.Axis)item.AxisParameter.CurrentAxisId);
                // 获取急停减速度
                item.AxisParameter.TargetKillDeceleration = (double)AcsControllerProvider.AcsController.GetKillDeceleration((ACS.SPiiPlusNET.Axis)item.AxisParameter.CurrentAxisId);
            }
        }
        /// <summary>
        /// 循环从控制器读取数据
        /// </summary>
        private void GetDataFromController()
        {
            if (AcsControllerProvider.AcsController.IsConnected)
            {
                //var tasks = AxisProvider.AcsMotionAxes.Select(axis => UpdateAxisDataAsync(axis));
                //await Task.WhenAll(tasks);

                foreach (var item in AxisProvider.AcsMotionAxes)
                {
                    // 右限位
                    bool RL = AcsControllerProvider.AcsController.ReadIntVariableByBit("FMASK", 0, ProgramBuffer.ACSC_NONE, item.AxisParameter.CurrentAxisId, item.AxisParameter.CurrentAxisId);
                    // 左限位
                    bool LL = AcsControllerProvider.AcsController.ReadIntVariableByBit("FMASK", 1, ProgramBuffer.ACSC_NONE, item.AxisParameter.CurrentAxisId, item.AxisParameter.CurrentAxisId);
                    // 右软限位
                    bool SRL = AcsControllerProvider.AcsController.ReadIntVariableByBit("FMASK", 5, ProgramBuffer.ACSC_NONE, item.AxisParameter.CurrentAxisId, item.AxisParameter.CurrentAxisId);
                    // 左软限位
                    bool SLL = AcsControllerProvider.AcsController.ReadIntVariableByBit("FMASK", 6, ProgramBuffer.ACSC_NONE, item.AxisParameter.CurrentAxisId, item.AxisParameter.CurrentAxisId);
                    // 获取Motor错误
                    var faulted = AcsControllerProvider.AcsController.GetFault((ACS.SPiiPlusNET.Axis)item.AxisParameter.CurrentAxisId);
                    // 获取电机回参状态
                    var referenced = AcsControllerProvider.AcsController.ReadAxisIsReferenced((ACS.SPiiPlusNET.Axis)item.AxisParameter.CurrentAxisId);
                    // 获取电机状态
                    var motorStates = AcsControllerProvider.AcsController.GetMotorStates((ACS.SPiiPlusNET.Axis)item.AxisParameter.CurrentAxisId);
                    // 获取回参位置
                    var currentReferencePosition = AcsControllerProvider.AcsController.GetCurrentReferencePosition((ACS.SPiiPlusNET.Axis)item.AxisParameter.CurrentAxisId);
                    // 获取反馈位置
                    var currentFeedbackPosition = AcsControllerProvider.AcsController.GetCurrentFeedbackPosition((ACS.SPiiPlusNET.Axis)item.AxisParameter.CurrentAxisId);
                    // 获取位置误差
                    var currentPositionError = (double)AcsControllerProvider.AcsController.GetCurrentPositionError((ACS.SPiiPlusNET.Axis)item.AxisParameter.CurrentAxisId);
                    // 获取速度反馈
                    var currentVelocity = (double)AcsControllerProvider.AcsController.GetCurrentVelocity((ACS.SPiiPlusNET.Axis)item.AxisParameter.CurrentAxisId);
                    // 获取电机错误码
                    var motorErrorId = AcsControllerProvider.AcsController.GetMotorError((ACS.SPiiPlusNET.Axis)item.AxisParameter.CurrentAxisId);
                    // 获取错误码详细信息
                    var motorErrorMessage = AcsControllerProvider.AcsController.GetErrorString(item.AxisState.MotorErrorId);
                    // 获取软限位
                    var currentSoftLeftLimit = (double)AcsControllerProvider.AcsController.ReadVariable("SLLIMIT", ProgramBuffer.ACSC_NONE, item.AxisParameter.CurrentAxisId, item.AxisParameter.CurrentAxisId);
                    var currentSoftRightLimit = (double)AcsControllerProvider.AcsController.ReadVariable("SRLIMIT", ProgramBuffer.ACSC_NONE, item.AxisParameter.CurrentAxisId, item.AxisParameter.CurrentAxisId);
                    // 获取急停减速度
                    var currentKillDeceleration = (double)AcsControllerProvider.AcsController.GetKillDeceleration((ACS.SPiiPlusNET.Axis)item.AxisParameter.CurrentAxisId);
                    // 获取当前加速度
                    var currentAcceleration = (double)AcsControllerProvider.AcsController.AcsInstance.GetAcceleration((ACS.SPiiPlusNET.Axis)item.AxisParameter.CurrentAxisId);
                    // 获取当前减速度
                    var currentDeceleration = (double)AcsControllerProvider.AcsController.AcsInstance.GetDeceleration((ACS.SPiiPlusNET.Axis)item.AxisParameter.CurrentAxisId);
                    // 获取加加速
                    var currentJerk = (double)AcsControllerProvider.AcsController.AcsInstance.GetJerk((ACS.SPiiPlusNET.Axis)item.AxisParameter.CurrentAxisId);

                    /*******************************使用线程调度更新UI数据******************************/
                    //Application.Current.Dispatcher.BeginInvoke(new Action(() =>
                    //{
                        // 获取Motor错误
                        item.AxisState.Faulted = faulted;
                        // 获取电机回参状态
                        item.AxisState.Referenced = referenced;
                        // 获取电机状态
                        item.AxisState.MotorStates = motorStates;
                        // 刷新状态指示灯
                        if ((item.AxisState.MotorStates & MotorStates.ACSC_MST_MOVE) != 0) item.AxisState.Moving = true; else item.AxisState.Moving = false;
                        if ((item.AxisState.MotorStates & MotorStates.ACSC_MST_INPOS) != 0) item.AxisState.InPosition = true; else item.AxisState.InPosition = false;
                        if ((item.AxisState.MotorStates & MotorStates.ACSC_MST_ACC) != 0) item.AxisState.Accelerating = true; else item.AxisState.Accelerating = false;
                        if ((item.AxisState.MotorStates & MotorStates.ACSC_MST_ENABLE) != 0) item.AxisState.Enabled = true; else item.AxisState.Enabled = false;

                        // 获取回参位置
                        item.AxisParameter.CurrentReferencePosition = currentReferencePosition;
                        // 获取反馈位置
                        item.AxisParameter.CurrentFeedbackPosition = currentFeedbackPosition;
                        // 获取位置误差
                        item.AxisParameter.CurrentPositionError = currentPositionError;
                        // 获取速度反馈
                        item.AxisParameter.CurrentVelocity = currentVelocity;
                        // 获取电机错误码
                        item.AxisState.MotorErrorId = motorErrorId;
                        // 获取错误码详细信息
                        item.AxisState.MotorErrorMessage = motorErrorMessage;
                        // 获取软限位
                        item.AxisParameter.CurrentSoftLeftLimit = currentSoftLeftLimit;
                        item.AxisParameter.CurrentSoftRightLimit = currentSoftRightLimit;
                        // 获取急停减速度
                        item.AxisParameter.CurrentKillDeceleration = currentKillDeceleration;
                        // 获取当前加速度
                        item.AxisParameter.CurrentAcceleration = currentAcceleration;
                        // 获取当前减速度
                        item.AxisParameter.CurrentDeceleration = currentDeceleration;
                        // 获取加加速
                        item.AxisParameter.CurrentJerk = currentJerk;

                        item.AxisState.IsHardwareLimitActivated = RL && LL;
                        item.AxisState.IsSoftwareLimitActivated = SRL && SLL;
                    //}));
                }

            }
        }
        //private async Task UpdateAxisDataAsync(AcsMotionAxis axis)
        //{
        //    // 右限位
        //    bool RL = await Task.Run(() => AcsControllerProvider.AcsController.ReadIntVariableByBit("FMASK", 0, ProgramBuffer.ACSC_NONE, axis.AxisParameter.CurrentAxisId, axis.AxisParameter.CurrentAxisId));
        //    // 左限位
        //    bool LL = await Task.Run(() => AcsControllerProvider.AcsController.ReadIntVariableByBit("FMASK", 1, ProgramBuffer.ACSC_NONE, axis.AxisParameter.CurrentAxisId, axis.AxisParameter.CurrentAxisId));
        //    // 右软限位
        //    bool SRL = await Task.Run(() => AcsControllerProvider.AcsController.ReadIntVariableByBit("FMASK", 5, ProgramBuffer.ACSC_NONE, axis.AxisParameter.CurrentAxisId, axis.AxisParameter.CurrentAxisId));
        //    // 左软限位
        //    bool SLL = await Task.Run(() => AcsControllerProvider.AcsController.ReadIntVariableByBit("FMASK", 6, ProgramBuffer.ACSC_NONE, axis.AxisParameter.CurrentAxisId, axis.AxisParameter.CurrentAxisId));
        //    // 获取Motor错误
        //    var faulted = await Task.Run(() => AcsControllerProvider.AcsController.GetFault((ACS.SPiiPlusNET.Axis)axis.AxisParameter.CurrentAxisId));
        //    // 获取电机回参状态
        //    var referenced = await Task.Run(() => AcsControllerProvider.AcsController.ReadAxisIsReferenced((ACS.SPiiPlusNET.Axis)axis.AxisParameter.CurrentAxisId));
        //    // 获取电机状态
        //    var motorStates = await Task.Run(() => AcsControllerProvider.AcsController.GetMotorStates((ACS.SPiiPlusNET.Axis)axis.AxisParameter.CurrentAxisId));
        //    // 获取回参位置
        //    var currentReferencePosition = await Task.Run(() => AcsControllerProvider.AcsController.GetCurrentReferencePosition((ACS.SPiiPlusNET.Axis)axis.AxisParameter.CurrentAxisId));
        //    // 获取反馈位置
        //    var currentFeedbackPosition = await Task.Run(() => AcsControllerProvider.AcsController.GetCurrentFeedbackPosition((ACS.SPiiPlusNET.Axis)axis.AxisParameter.CurrentAxisId));
        //    // 获取位置误差
        //    var currentPositionError = await Task.Run(() => (double)AcsControllerProvider.AcsController.GetCurrentPositionError((ACS.SPiiPlusNET.Axis)axis.AxisParameter.CurrentAxisId));
        //    // 获取速度反馈
        //    var currentVelocity = await Task.Run(() => (double)AcsControllerProvider.AcsController.GetCurrentVelocity((ACS.SPiiPlusNET.Axis)axis.AxisParameter.CurrentAxisId));
        //    // 获取电机错误码
        //    var motorErrorId = await Task.Run(() => AcsControllerProvider.AcsController.GetMotorError((ACS.SPiiPlusNET.Axis)axis.AxisParameter.CurrentAxisId));
        //    // 获取错误码详细信息
        //    var motorErrorMessage = await Task.Run(() => AcsControllerProvider.AcsController.GetErrorString(axis.AxisState.MotorErrorId));
        //    // 获取软限位
        //    var currentSoftLeftLimit = await Task.Run(() => (double)AcsControllerProvider.AcsController.ReadVariable("SLLIMIT", ProgramBuffer.ACSC_NONE, axis.AxisParameter.CurrentAxisId, axis.AxisParameter.CurrentAxisId));
        //    var currentSoftRightLimit = await Task.Run(() => (double)AcsControllerProvider.AcsController.ReadVariable("SRLIMIT", ProgramBuffer.ACSC_NONE, axis.AxisParameter.CurrentAxisId, axis.AxisParameter.CurrentAxisId));
        //    // 获取急停减速度
        //    var currentKillDeceleration = await Task.Run(() => (double)AcsControllerProvider.AcsController.GetKillDeceleration((ACS.SPiiPlusNET.Axis)axis.AxisParameter.CurrentAxisId));
        //    // 获取当前加速度
        //    var currentAcceleration = await Task.Run(() => (double)AcsControllerProvider.AcsController.AcsInstance.GetAcceleration((ACS.SPiiPlusNET.Axis)axis.AxisParameter.CurrentAxisId));
        //    // 获取当前减速度
        //    var currentDeceleration = await Task.Run(() => (double)AcsControllerProvider.AcsController.AcsInstance.GetDeceleration((ACS.SPiiPlusNET.Axis)axis.AxisParameter.CurrentAxisId));
        //    // 获取加加速
        //    var currentJerk = await Task.Run(() => (double)AcsControllerProvider.AcsController.AcsInstance.GetJerk((ACS.SPiiPlusNET.Axis)axis.AxisParameter.CurrentAxisId));

        //    /*******************************使用线程调度更新UI数据******************************/
        //    await Application.Current.Dispatcher.InvokeAsync(() =>
        //    {
        //        // 获取Motor错误
        //        axis.AxisState.Faulted = faulted;
        //        // 获取电机回参状态
        //        axis.AxisState.Referenced = referenced;
        //        // 获取电机状态
        //        axis.AxisState.MotorStates = motorStates;
        //        // 刷新状态指示灯
        //        if ((axis.AxisState.MotorStates & MotorStates.ACSC_MST_MOVE) != 0) axis.AxisState.Moving = true; else axis.AxisState.Moving = false;
        //        if ((axis.AxisState.MotorStates & MotorStates.ACSC_MST_INPOS) != 0) axis.AxisState.InPosition = true; else axis.AxisState.InPosition = false;
        //        if ((axis.AxisState.MotorStates & MotorStates.ACSC_MST_ACC) != 0) axis.AxisState.Accelerating = true; else axis.AxisState.Accelerating = false;
        //        if ((axis.AxisState.MotorStates & MotorStates.ACSC_MST_ENABLE) != 0) axis.AxisState.Enabled = true; else axis.AxisState.Enabled = false;

        //        // 获取回参位置
        //        axis.AxisParameter.CurrentReferencePosition = currentReferencePosition;
        //        // 获取反馈位置
        //        axis.AxisParameter.CurrentFeedbackPosition = currentFeedbackPosition;
        //        // 获取位置误差
        //        axis.AxisParameter.CurrentPositionError = currentPositionError;
        //        // 获取速度反馈
        //        axis.AxisParameter.CurrentVelocity = currentVelocity;
        //        // 获取电机错误码
        //        axis.AxisState.MotorErrorId = motorErrorId;
        //        // 获取错误码详细信息
        //        axis.AxisState.MotorErrorMessage = motorErrorMessage;
        //        // 获取软限位
        //        axis.AxisParameter.CurrentSoftLeftLimit = currentSoftLeftLimit;
        //        axis.AxisParameter.CurrentSoftRightLimit = currentSoftRightLimit;
        //        // 获取急停减速度
        //        axis.AxisParameter.CurrentKillDeceleration = currentKillDeceleration;
        //        // 获取当前加速度
        //        axis.AxisParameter.CurrentAcceleration = currentAcceleration;
        //        // 获取当前减速度
        //        axis.AxisParameter.CurrentDeceleration = currentDeceleration;
        //        // 获取加加速
        //        axis.AxisParameter.CurrentJerk = currentJerk;

        //        axis.AxisState.IsHardwareLimitActivated = RL && LL;
        //        axis.AxisState.IsSoftwareLimitActivated = SRL && SLL;
        //    });
        //}
    }
}
